home *** CD-ROM | disk | FTP | other *** search
- Date: Mon, 14 Feb 94 13:42:01 PST
- From: hyc@hanauma.jpl.nasa.gov (Howard Chu)
- Message-Id: <9402142142.AA07231@hanauma.jpl.nasa.gov>
- To: ersmith@netcom.com, mint@atari.archive.umich.edu
- Subject: Re: user-written interrupt handlers
-
- >Date: Mon, 14 Feb 1994 11:47:04 -0800
- >From: ersmith@netcom.com (Eric R. Smith)
- >
- >I would think that any user-supplied interrupt handlers should be provided
- >as device drivers; they can then call into the kernel via the table that
- >MiNT provides, and don't have to worry about going through trap #1.
-
- Well, I decided I was taking an impossible tack, so I tried again from a
- different angle... Now I have a new DOS call Psiginter(vec,sig) which will
- install an interrupt handler for the user, that will send the calling process
- the signal sig when the given interrupt occurs. I basically copied the Do_sig
- code in intr.spp, pointing it to a routine that just does post_sig as
- specified. Unfortunately, this doesn't work reliably; I get all kinds of
- bizarre crashes. I don't suppose any of you could look it over and point out
- what I'm not catching...?
-
- The particular application is to handle DMA sound interrupts, fyi...
-
-
- *** 1.1 1994/02/13 11:00:22
- --- intr.spp 1994/02/14 21:40:17
- ***************
- *** 225,228 ****
- --- 225,283 ----
-
- ;
- + ; Generic routine for handling any user-specified interrupts. On 68000, the
- + ; vector number is stored in the high byte of the program counter.
- + ;
- + XDEF _new_intr
- +
- + _new_intr:
- + ; ori.w #$0700,sr
- + subq.w #2,sp ; reserve space for fake frame word
- + move.l d0,-(sp) ; save d0
- +
- + %ifndef ONLY030
- + tst.w ($59e.w) ; is frame format on stack?
- + bne.s nvec ; yes, go use it
- + bsr.s ndummy ; push PC to stack
- + nop
- + ndummy:
- + move.l (sp)+,d0 ; pop PC to d0
- + swap d0 ; move hi word to lo word
- + lsr.w #6,d0 ; move hi byte into vector offset position
- + andi.b #$fc,d0 ; clear any garbage from lo 2 bits
- + bra.s ngot ; continue
- + nvec:
- + %endif
- + move.w 12(sp),d0 ; get frame word
- + andi.w #$ffc,d0 ; mask down to vector offset
- + ngot:
- + move.w d0,4(sp) ; store vector offset
- + move.l (sp)+,d0 ; restore d0
- + tst.w _in_kernel ; did we interrupt the kernel?
- + bne.s kern_intr ; yes ...
- + move.l _curproc,-(sp)
- + addq.l #4,(sp) ; push offset of save area
- + jsr _build_context
- + move.w 4(sp),d0 ; pull vector offset from stack to d0
- + move.l _curproc,a4
- + move.l (a4),sp ; get into system stack
- + move.w d0,-(sp) ; save vector offset
- + jsr _enter_kernel
- + jsr _sig_user ; send signal
- + ori.w #$0700,sr ; spl7()
- + jsr _leave_kernel ; leave kernel
- + addq.w #4,a4 ; get context save area address
- + move.l a4,-(sp) ; push it
- + jsr _restore_context ; restore the context
- +
- + kern_intr:
- + movem.l d0-d2/a0-a2,-(sp) ; save regs
- + move.w 24(sp),-(sp) ; copy vector offset up
- + jsr _sig_user ; send signal
- + addq.w #2,sp ; pop copy of vector offset
- + movem.l (sp)+,d0-d2/a0-a2 ; restore regs
- + addq.w #2,sp ; pop vector offset
- + rte
- +
- + ;
- ; New bus error handler for memory protection: get the ssp and
- ; put it in the proc structure before calling
- *** 1.1 1994/02/14 21:38:04
- --- dossig.c 1994/02/14 21:35:30
- ***************
- *** 211,212 ****
- --- 211,289 ----
- return 0;
- }
- +
- + /*
- + * p_sigintr: Set an exception vector to send us the specified signal.
- + */
- +
- + typedef struct usig {
- + int vec;
- + int sig;
- + PROC *proc;
- + struct usig *next;
- + } usig;
- +
- + static usig *usiglst;
- + extern long mcpu;
- +
- + long ARGS_ON_STACK
- + p_siginter(vec, sig)
- + int vec;
- + int sig;
- + {
- + extern void new_intr();
- + long vec2;
- + usig *new;
- +
- + if (!sig) /* ignore signal 0 */
- + return 0;
- +
- + vec2 = (long) new_intr;
- +
- + #ifndef ONLY030
- + if (mcpu == 0)
- + vec2 |= vec << 24;
- + #endif
- + new = kmalloc(sizeof(usig));
- + new->vec = vec;
- + new->sig = sig;
- + new->proc = curproc;
- + new->next = usiglst;
- + usiglst = new;
- +
- + return setexc(vec, vec2);
- + }
- +
- + /*
- + * Find the process that requested this interrupt, and send it a signal.
- + */
- + void ARGS_ON_STACK
- + sig_user(vec)
- + int vec;
- + {
- + usig *ptr;
- +
- + vec >>= 2;
- + for (ptr = usiglst; ptr; ptr=ptr->next)
- + if (vec == ptr->vec) {
- + if (ptr->proc->wait_q != ZOMBIE_Q &&
- + ptr->proc->wait_q != TSR_Q) {
- + post_sig(ptr->proc, ptr->sig);
- + }
- + if (vec >= 64 && vec < 80) {
- + /*
- + * Clear in-service bit for ST MFP interrupts
- + */
- + char *mfp, c;
- +
- + if (vec < 72) /* Register B */
- + mfp = (char *)0xfffffa11L;
- + else /* Register A */
- + mfp = (char *)0xfffffa0fL;
- + c = 1 << (vec & 7);
- +
- + *mfp = ~c;
- + }
- +
- + break;
- + }
- + }
-